<?php

#<editor-fold defaultstate="collapsed" desc="CCore::Using">
CCore::Using('base.collection');
CCore::Using('base.datapointer');
CCore::Using('mime.constants');
CCore::Using('mime.parameter');
#</editor-fold>

class CCoreMimeHeader
{
	#<editor-fold defaultstate="collapsed" desc="private">
	/**
	 * @var string
	 */
	private $_sName;

	/**
	 * @var	string
	 */
	private $_sValue;
	#</editor-fold>

	/**
	 * @return	CCoreMimeHeader
	 */
	public function __construct($sName, $sValue = '')
	{
		CCore::CheckTypes(array('$sName', '$sValue'));
		
		$this->_sName = trim($sName);
		$this->_sValue = trim($sValue);
	}

	/**
	 * @return	string
	 */
	public function Value()
	{
		return $this->_sValue;
	}

	/**
	 * @return	string
	 */
	public function Name()
	{
		return $this->_sName;
	}
}

class CCoreMimeHeadersCollection extends ACoreBaseCollection
{
	#<editor-fold defaultstate="collapsed" desc="protected">
	/**
	 * @return	CCoreBaseDataPointer
	 */
	protected $oDataPointer;
	#</editor-fold>
	
	/**
	 * @param	CCoreBaseDataPointer	&$oDataPointer
	 * @return	CCoreMimeHeadersCollection
	 */
	public function __construct(CCoreBaseDataPointer &$oDataPointer)
	{
		CCore::CheckTypes(array('$oDataPointer'));

		$this->oDataPointer =& $oDataPointer;
		$this->_parse();
	}
	
	/**
	 * @param	CCoreMimeHeader	$oMimeHeader
	 * @return	void
	 */
	public function Add(CCoreMimeHeader $oMimeHeader)
	{
		CCore::CheckTypes(array('$oMimeHeader'));

		parent::Add($oMimeHeader);
	}

	/**
	 * @return	string
	 */
	public function GetBoundaryValue()
	{
		return $this->_getParamValueFromHeader(C_MIME_HEADERS_CONTENT_TYPE, 'boundary');
	}
	
	/**
	 * @param	string	$sHeaderName
	 * @return	string
	 */
	public function GetValueByName($sHeaderName)
	{
		CCore::CheckTypes(array('$sHeaderName'));

		$oHeader =& $this->_getByName($sHeaderName);
		return (null !== $oHeader) ? $oHeader->Value() : '';
	}

	/**
	 * @return	string
	 */
	private function _getParamValueFromHeader($sHeaderName, $sParamName)
	{
		CCore::CheckTypes(array('$sHeaderName', '$sParamName'));

		$sReturn = '';
		$sMimeHeaderValue =& $this->GetValueByName($sHeaderName);
		if (strlen($sMimeHeaderValue) > 0)
		{
			$oParameters = new CCoreMimeParametersCollection($sMimeHeaderValue);
			$sReturn = $oParameters->GetParamValueByName($sParamName);
		}

		return $sReturn;
	}

	/**
	 * @param	string		$sHeaderName
	 * @return	CCoreMimeHeader
	 */
	private function &_getByName($sHeaderName)
	{
		CCore::CheckTypes(array('$sHeaderName'));

		$sHeaderNameLower = strtolower($sHeaderName);
		$aHeaders =& $this->GetArray();
		foreach ($aHeaders as $oHeader)
		{
			if ($sHeaderNameLower === strtolower($oHeader->Name()))
			{
				return $oHeader;
			}
		}
		$nReturnNull = null;
		return $nReturnNull;
	}

	/**
	 * @return void
	 */
	private function _parse()
	{
		$this->Clear();
		$this->oDataPointer->Seek(0);
		
		$sName = $sValue = null;
		while (true)
		{
			$sBuffer = $this->oDataPointer->GetBufferUntilString("\n");
			if (false === $sBuffer)
			{
				if (null !== $sName)
				{
					$this->Add(new CCoreMimeHeader($sName, $sValue));
				}
				break;
			}

			$sFirstChar = substr($sBuffer, 0, 1);
			if (($sFirstChar === ' ' || $sFirstChar === "\t") && null !== $sValue)
			{
				$sValue .= $sBuffer;
			}
			else
			{
				if (null !== $sName)
				{
					$this->Add(new CCoreMimeHeader($sName, $sValue));
					$sName = $sValue = null;
				}

				$aHeaderParts = explode(':', $sBuffer, 2);
				$sName = $aHeaderParts[0];
				$sValue = isset($aHeaderParts[1]) ? $aHeaderParts[1] : '';
			}
		}
	}
}